<template>
  <a-card :bordered="false" :style="{ minHeight: `${layoutContentHeight - pageHeaderHeight}px` }">
    <a-spin :spinning="loading">
      <a-form :form="form">
        <a-form-item
          :label="$t('messageCenter.app.tempCode')"
          :labelCol="labelCol"
          :wrapperCol="wrapperCol"
          v-bind="validator.codeValidProps"
        >
          <s-input
            :disabled="!!id || !canEdit"
            v-decorator="[
              'code',
              {
                rules: [
                  {
                    validator: validator.codeValidator
                  }
                ]
              }
            ]"
            :limit="128"
          />
        </a-form-item>
        <a-form-item :label="$t('common.type')" :labelCol="labelCol" :wrapperCol="wrapperCol">
          <a-select
            :disabled="!canEdit"
            v-decorator="[
              'type',
              {
                rules: [
                  {
                    required: true,
                    message: $t('common.emptyErr', {
                      name: $t('common.type')
                    })
                  }
                ]
              }
            ]"
            style="width: 90%; display: inline-block; margin-right: 12px;"
          >
            <a-select-option v-for="(t, index) in types" :key="index" :value="t.name">{{ t.name }}</a-select-option>
          </a-select>
          <a
            :disabled="!canEdit"
            href="javascript:;"
            :style="{ display: 'inline-block', width: 'calc(10% - 12px)' }"
            @click="$refs.typeForm.add()"
          ><a-icon
            type="plus"
          /></a>
        </a-form-item>
        <a-form-item :label="$t('common.description')" :labelCol="labelCol" :wrapperCol="wrapperCol">
          <s-textarea :disabled="!canEdit" v-decorator="['description']" :limit="200" />
        </a-form-item>
        <a-form-item :label="$t('messageCenter.app.upLevel')" :labelCol="labelCol" :wrapperCol="wrapperCol">
          <a-button
            :disabled="!canEdit"
            type="primary"
            size="small"
            style="margin-bottom: 36px;"
            @click="onClickAddLevel"
          >{{ $t('button.add') }}</a-button
          >
          <a-timeline>
            <a-timeline-item v-for="(item, index) in fullLevelList" :key="item.tempId">
              <template v-if="item.isTime">
                <a-icon slot="dot" type="clock-circle-o" style="font-size: 14px;" />
                <span v-if="item.intervalTime" style="margin-right: 8px;">{{
                  formatSeconds(item.intervalTime * 60)
                }}</span>
                <a
                  :disabled="!canEdit"
                  v-if="item.intervalTime"
                  href="javascript:;"
                  @click="onDeleteInterval(item.tempId)"
                >
                  <a-icon type="delete" />
                </a>
                <a
                  :disabled="!canEdit"
                  v-if="!item.intervalTime"
                  href="javascript:;"
                  @click="$refs.timeForm.show({ tempId: item.tempId })"
                >{{ $t('button.add') }}</a
                >
              </template>
              <template v-else>
                <span style="margin-right: 8px;">{{ `第${noToChinese(parseInt(index / 2) + 1)}层` }}</span>
                <a
                  :disabled="!canEdit"
                  v-if="fullLevelList.length > 1"
                  href="javascript:;"
                  style="margin-right: 24px;"
                  @click="onDeleteLevel(item.tempId)"
                >
                  <a-icon type="delete" />
                </a>
                <!-- <a-tag
                    v-for="r in item.receiverList"
                    :key="r.id + '_' + r.isOrg"
                    closable
                    @close="e => onRemoveReceiver(e, item.tempId, r.id + '_' + r.isOrg)"
                  >
                    <a-icon v-if="r.isOrg" type="folder" />
                    {{ r.name }}
                  </a-tag> -->
                <template v-for="r in item.receiverList">
                  <a-tooltip v-if="r.name.length > 20" :key="r.id + '_' + r.isOrg" :title="r.name">
                    <a-tag
                      :key="r.id + '_' + r.isOrg"
                      :closable="canEdit"
                      @close="e => onRemoveReceiver(e, item.tempId, r.id + '_' + r.isOrg)"
                    >
                      {{ `${r.name.slice(0, 20)}...` }}
                    </a-tag>
                  </a-tooltip>
                  <a-tag
                    v-else
                    :key="r.id + '_' + r.isOrg"
                    :closable="canEdit"
                    @close="e => onRemoveReceiver(e, item.tempId, r.id + '_' + r.isOrg)"
                  >
                    {{ r.name }}
                  </a-tag>
                </template>
                <a :disabled="!canEdit" href="javascript:;" @click="onAddReceiver(item)"><a-icon type="plus"/></a>
              </template>
            </a-timeline-item>
          </a-timeline>
        </a-form-item>
        <a-form-item :label="$t('messageCenter.app.cycle')" :labelCol="labelCol" :wrapperCol="wrapperCol">
          <a-input-number
            :disabled="!canEdit"
            v-model="cycle"
            :min="1"
            :max="100"
            :precision="0"
            @blur="onBlurCycle"
            style="margin-right: 8px;"
          />
          <span style="margin-right: 24px;">次</span>
          <span v-if="cycle > 1">
            <a-tooltip placement="top">
              <template slot="title">
                <span>{{ $t('messageCenter.app.cycleTimeInterval') }}</span>
              </template>
              <a
                :disabled="!canEdit"
                href="javascript:;"
                style="font-size: 16px; margin-right: 8px;"
                @click="$refs.cycleForm.show({ intervalTime })"
              >
                <a-icon type="clock-circle" />
              </a>
            </a-tooltip>

            <span>{{ formatSeconds(intervalTime * 60) }}</span>
          </span>
        </a-form-item>
        <a-form-item v-action:save style="text-align: center;">
          <a-button style="margin-right: 20px;" @click="handleSubmit" type="primary">{{
            $t('common.submit')
          }}</a-button>
          <a-button @click="handleReset">{{ $t('common.reset') }}</a-button>
        </a-form-item>
      </a-form>
    </a-spin>
    <type-form ref="typeForm" @ok="onSubmitType" />
    <time-form ref="timeForm" @ok="onSubmitAddLevelInterval" />
    <time-form ref="cycleForm" @ok="onSubmitAddCycleInterval" />
    <select-modal
      ref="selectModalMember"
      :title="$t('messageCenter.app.chooseReceiver')"
      :subTitle="$t('messageCenter.app.organization')"
      :tree-data="filteredOrgTree"
      :inputNumber="false"
      :treeCheckable="true"
      :treeCheckStrictly="true"
      :select-tree-node="loadMemberUserData"
      :defaultSelectedTreeKeys="selectedOrgTreeKeys"
      @sure="onSubmitReceiver"
    />
  </a-card>
</template>

<script>
import cloneDeep from 'lodash.clonedeep'
import { asyncValidateMixin, layoutMixin } from '@/utils/mixin'
import { noToChinese, uuidv4, formatSeconds, setArrayToTree, breadFirstTree } from '@/utils/util'
import FooterToolBar from '@/components/FooterToolbar'
import { SInput, STextarea } from '@/components'
import SelectModal from '@/components/SelectModal/SelectModal'
import TypeForm from './TypeForm'
import { getEscalateTypeList, getOrgList, getUserList } from '@/api/messageCenter/mos'
import { getEscalate, createEscalate, updateEscalate, validateEscalate } from '@/api/messageCenter/escalate'

import TimeForm from './TimeForm'
export default {
  name: 'EscalateDetail',
  components: {
    FooterToolBar,
    SInput,
    STextarea,
    SelectModal,
    TimeForm,
    TypeForm
  },
  mixins: [asyncValidateMixin, layoutMixin],
  data () {
    return {
      loading: false,
      labelCol: {
        lg: { span: 7 },
        sm: { span: 7 }
      },
      wrapperCol: {
        lg: { span: 10 },
        sm: { span: 17 }
      },
      id: 0,
      types: [],
      form: this.$form.createForm(this),
      confirmLoading: false,
      fullLevelList: [],
      varList: [],
      orgTree: [], // 原始部门树
      selectedMemberKeys: [], // 已选人员ids
      selectedOrgTreeKeys: [], // 已选部门树ids
      filteredOrgTree: [], // 可选部门树
      cycle: 1,
      intervalTime: 30,
      selectedLevel: {},
      canEdit: this.$auth('save', this.$route.meta.permissionId)
    }
  },
  computed: {
    columns () {
      return [
        {
          title: '变量名',
          dataIndex: 'ossObjKey',
          scopedSlots: { customRender: 'name' }
        },
        {
          title: '描述',
          dataIndex: 'status',
          scopedSlots: { customRender: 'fileSize' }
        },
        {
          title: this.$t('common.action'),
          dataIndex: 'action',
          width: 180,
          align: 'center',
          scopedSlots: { customRender: 'action' },
          fixed: 'right'
        }
      ]
    }
  },
  created () {
    const id = this.$route.params.id
    this.id = id
    this.init()
    this.initAsyncValidateMixin()
  },
  methods: {
    formatSeconds,
    noToChinese,
    init () {
      this.getTypeList()
      this.getOrgTree()
      if (this.id) {
        this.initEscalate(this.id)
      } else {
        this.fullLevelList = [
          {
            tempId: uuidv4(),
            level: 0,
            receiverList: [],
            isTime: false
          }
        ]
      }
    },

    /**
     * 初始化验证器
     */
    initAsyncValidateMixin () {
      const validateFields = [
        {
          fieldName: 'code',
          caller: validateEscalate,
          extraParams: {
            id: this.id
          }
        }
      ]
      this.$_asyncValidateMixin_init(validateFields)
    },

    getTypeList () {
      getEscalateTypeList().then(res => {
        this.types = res.data
      })
    },

    getOrgTree () {
      getOrgList().then(res => {
        if (res.data) {
          const tempTree = setArrayToTree({ data: res.data, pid: 'parentId' })
          breadFirstTree(
            tempTree,
            jn => {
              jn.key = jn.id
              jn.title = jn.name
              return true
            },
            'children'
          )
          this.orgTree = tempTree
        }
      })
    },

    loadMemberUserData (node, resolve) {
      getUserList({ id: node.id, pageNo: 1, pageSize: 99999 }).then(res => {
        const data = res.data.data
        data.forEach(item => {
          item.label = `[${item.jobNumber}]${item.name}`
          item.value = item.id
          if (this.selectedMemberKeys.includes(item.id)) {
            item.disabled = true
          }
        })
        resolve(data)
      })
    },

    initEscalate (id) {
      this.loading = true
      getEscalate({ id })
        .then(res => {
          const { upgradeNotice, upgradeNoticeDetails } = res.data
          if (upgradeNotice) {
            const { code, type, description, cycle, intervalTime, ...otherConfig } = upgradeNotice
            this.templateConfig = otherConfig
            this.cycle = cycle
            this.intervalTime = intervalTime
            this.$nextTick(() => {
              this.form.setFieldsValue({ code, type, description: description || '' })
            })
          }
          this.fullLevelList = this.genFullLevelList(upgradeNoticeDetails)
        })
        .finally(() => {
          this.loading = false
        })
    },

    genFullLevelList (arr) {
      const fullLevelList = []
      for (let i = 0; i < arr.length; i++) {
        if (i !== 0) {
          fullLevelList.push({
            tempId: uuidv4(),
            intervalTime: arr[i].intervalTime,
            isTime: true
          })
        }
        const receiverList = []
        const unionIdArr = arr[i].unionIds.split(',')
        const unionNameArr = arr[i].unionNames.split(',')
        const isOrgArr = arr[i].types.split(',')
        for (let j = 0; j < unionIdArr.length; j++) {
          const tempArr = unionIdArr[j].split('_')
          tempArr.shift()
          receiverList.push({
            id: tempArr.length > 1 ? tempArr.join('_') : parseInt(tempArr[0]),
            name: unionNameArr[j],
            isOrg: parseInt(isOrgArr[j])
          })
        }
        fullLevelList.push({
          id: arr[i].id,
          level: i,
          receiverList,
          isTime: false,
          tempId: uuidv4()
        })
      }
      return fullLevelList
    },

    onSubmitType (values) {
      this.getTypeList()
    },

    onClickAddLevel () {
      const level = Math.floor((this.fullLevelList.length + 1) / 2)
      this.fullLevelList = this.fullLevelList.concat([
        {
          tempId: uuidv4(),
          intervalTime: 0,
          isTime: true
        },
        {
          tempId: uuidv4(),
          level,
          receiverList: [],
          isTime: false
        }
      ])
    },

    onDeleteLevel (tempId) {
      const index = this.fullLevelList.findIndex(ele => ele.tempId === tempId)
      if (index === 0) {
        this.fullLevelList = this.fullLevelList.filter((ele, idx) => {
          return idx !== index && idx !== index + 1
        })
      } else {
        this.fullLevelList = this.fullLevelList.filter((ele, idx) => {
          return idx !== index && idx !== index - 1
        })
      }
    },

    onDeleteInterval (tempId) {
      this.fullLevelList = this.fullLevelList.map(ele => {
        if (ele.tempId === tempId) {
          ele.intervalTime = 0
        }
        return ele
      })
    },

    onAddReceiver (item) {
      this.selectedLevel = item
      const selectedOrgIds = []
      const selectedMemberKeys = []
      for (const obj of item.receiverList) {
        if (obj.isOrg === 1) {
          selectedOrgIds.push(obj.id)
        } else if (obj.isOrg === 2) {
          selectedOrgIds.push(parseInt(obj.id.split('_')[0]))
        } else if (obj.isOrg === 0) {
          selectedMemberKeys.push(obj.id)
        }
      }
      const tree = cloneDeep(this.orgTree)
      breadFirstTree(
        tree,
        jn => {
          if (selectedOrgIds.includes(jn.id)) {
            jn.disabled = true
            breadFirstTree(
              jn.children,
              el => {
                el.disabled = true
                return true
              },
              'children'
            )
          }
          return true
        },
        'children'
      )
      this.selectedOrgTreeKeys = selectedOrgIds
      this.selectedMemberKeys = selectedMemberKeys
      this.filteredOrgTree = tree
      this.$refs.selectModalMember.open()
    },

    onSubmitReceiver (values) {
      const list = values.map(ele => {
        const rt = {
          id: ele.id,
          name: ele.name,
          isOrg: 0
        }
        if (ele.hasOwnProperty('children')) {
          rt.isOrg = 1
          if (ele.extra) {
            rt.id = `${ele.id}_${ele.extra}`
            rt.name = `${ele.name}_${ele.extra}`
            rt.isOrg = 2
          }
        }
        return rt
      })
      this.fullLevelList = this.fullLevelList.map(ele => {
        if (ele.tempId === this.selectedLevel.tempId) {
          ele.receiverList = ele.receiverList.concat(list)
        }
        return ele
      })
      this.$refs.selectModalMember.close()
    },

    /**
     * 此处id其实是id_isOrg结构，为了规避人员id和组织id重复
     */
    onRemoveReceiver (e, levelId, id) {
      e.preventDefault()
      this.fullLevelList = this.fullLevelList.map(ele => {
        if (ele.tempId === levelId) {
          ele.receiverList = ele.receiverList.filter(r => r.id + '_' + r.isOrg !== id)
        }
        return ele
      })
    },

    onSubmitAddLevelInterval (values) {
      const { tempId, intervalTime } = values
      this.fullLevelList = this.fullLevelList.map(ele => {
        if (ele.tempId === tempId) {
          ele.intervalTime = intervalTime
        }
        return ele
      })
    },

    onBlurCycle (e) {
      if (!e.target.value) {
        this.cycle = 1
      }
    },

    onSubmitAddCycleInterval (values) {
      this.intervalTime = values.intervalTime
    },

    validateLevelList () {
      let valid = true
      for (let i = 0; i < this.fullLevelList.length; i++) {
        const item = this.fullLevelList[i]
        if (item.isTime) {
          if (!item.intervalTime) {
            this.$notification.error({
              message: '错误',
              description: '层级时间间隔不能为空'
            })
            valid = false
            break
          }
        } else {
          if (item.receiverList.length === 0) {
            this.$notification.error({
              message: '错误',
              description: '通知接收人员不能为空'
            })
            valid = false
            break
          }
        }
      }
      return valid
    },

    convertToOriginList () {
      const rt = []
      for (let i = 0; i < this.fullLevelList.length; i += 2) {
        const item = this.fullLevelList[i]
        const obj = {
          id: item.id || 0,
          codeId: this.id,
          unionIds: item.receiverList.map(ele => `${ele.isOrg}_${ele.id}`).join(','),
          unionNames: item.receiverList.map(ele => ele.name).join(','),
          types: item.receiverList.map(ele => ele.isOrg).join(','),
          intervalTime: 0
        }
        rt.push(obj)
      }
      for (let i = 1; i < this.fullLevelList.length - 1; i += 2) {
        rt[parseInt(i / 2) + 1].intervalTime = this.fullLevelList[i].intervalTime
      }
      return rt
    },

    handleSubmit () {
      if (this.validateLevelList()) {
        const {
          form: { validateFields, getFieldsValue }
        } = this
        const fieldNames = this.id ? ['type'] : ['code', 'type']
        validateFields(fieldNames, (errors, values) => {
          if (!errors) {
            const { code, type, description } = getFieldsValue()
            const model = {
              upgradeNotice: {
                id: this.id || null,
                code: code ? code.trim() : '',
                type,
                description: description ? description.trim() : '',
                cycle: this.cycle,
                intervalTime: this.intervalTime
              },
              upgradeNoticeDetails: this.convertToOriginList()
            }
            if (!this.id) {
              createEscalate(model)
                .then(res => {
                  this.$router.push({ name: 'escalate' })
                })
                .finally(() => {})
            } else {
              updateEscalate(model)
                .then(res => {
                  this.$router.push({ name: 'escalate' })
                })
                .finally(() => {})
            }
          }
        })
      }
    },

    handleReset () {
      this.init()
    }
  }
}
</script>

<style></style>
